#include <iostream>
#include <stdio.h>

using namespace std;

//环境类ForumAccount（论坛账号类）
class AbstractState;
class ForumAccount{
public:
	ForumAccount(string name);
	
	void setState(AbstractState *state){
		this->state = state;
	}
	
	AbstractState* getState(){
		return this->state;
	}
	
	string getName(){
		return this->name;
	}
	
	//定义在后面 
	void downloadFile(int score);
	
	void writeNote(int score);
	
	void replyNote(int score);
private:
	AbstractState *state;
	string name;
};

//抽象类AbstractState（账号状态类）
class AbstractState{
public:
	virtual void checkState(int score) = 0;
	
	virtual void downloadFile(int score){
		cout << acc->getName() << "下载文件，扣除" << score << "积分。" << endl;
		this->point -= score;
		checkState(score);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl; 
	}
	
	virtual void writeNote(int score){
		cout << acc->getName() << "发布留言,增加" << score << "积分。" << endl; 
		this->point += score;
		checkState(score);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	virtual void replyNote(int score){
		cout << acc->getName() << "回复留言，增加" << score << "积分。" << endl; 
		this->point += score;
		checkState(score);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl;
	} 
	
	void setPoint(int point){
		this->point = point;
	}
	
	int getPoint(){
		return this->point;
	}
	
	void setStateName(string stateName){
		this->stateName = stateName;
	}
	
	ForumAccount* getAcc(){
		return acc;
	}
	
	string getStateName(){
		return stateName;
	}
protected:
	ForumAccount *acc;
	int point;
	string stateName;
	
};

//具体状态类PrimaryState（新手状态类）
class PrimaryState : public AbstractState{
public:
	PrimaryState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "新手";
	}
	
	PrimaryState(ForumAccount *acc){
		this->acc = acc;
		this->point = 0;
		this->stateName = "新手";
	}
	
	void downloadFile(int score){
		cout << "对不起，" << acc->getName() << "，您没有下载文件的权限!" << endl; 
	}
	
	void checkState(int socre);
}; 

//具体状态类MiddleState（高手状态类）
class MiddleState : public AbstractState{
public:
	MiddleState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "高手";
	}
	
	void writeNote(int score){
		cout << acc->getName() << "发布留言，增加" << score << "*2个积分。" << endl; 
		this->point += score*2;
		checkState(score);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	void checkState(int socre);
}; 

//具体状态类HighState（专家状态类）
class HighState : public AbstractState{
public:
	HighState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "专家";
	}
	
	void writeNote(int score){
		cout << acc->getName() << "发布留言，增加" << score << "*2个积分。" << endl; 
		this->point += score*2;
		checkState(score);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	void downloadFile(int score){
		cout << acc->getName() << "下载文件，扣除" << score << "/2个积分。" << endl;
		this->point -= score/2;
		checkState(score/2);
		cout << "剩余积分为：" << this->point << "，当前级别为："  << acc->getState()->getStateName() << "。" <<  endl; 
	}
	
	void checkState(int score);
}; 

//这里的定义需要放在这里，不然编译不通过，可以将声明和定义分开成.h和.cpp 
ForumAccount::ForumAccount(string name){
	this->name = name;
	this->state = new PrimaryState(this);
	cout << this->name << "注册成功!" << endl;
}
 
void ForumAccount::downloadFile(int score){
	state->downloadFile(score);
}
	
void ForumAccount::writeNote(int score){
	state->writeNote(score);
}
	
void ForumAccount::replyNote(int score){
	state->replyNote(score);
}
 
 
//这里存在内存泄漏，可改为智能指针 
void PrimaryState::checkState(int score){
	if(point>=1000){
		acc->setState(new HighState(this));
	}else if(point>=100){
		acc->setState(new MiddleState(this));
	}
}
 
void MiddleState::checkState(int score){
	if(point>=1000){
		acc->setState(new HighState(this));
	}else if(point<0){
		cout << "余额不足，操作失败!" << endl; 
		this->point += score;
	}else if(point<=100){
		acc->setState(new PrimaryState(this));
	}
}
 
void HighState::checkState(int score){
	if(point<0){
		cout << "余额不足，操作失败!" << endl; 
		this->point += score; 
	}else if(point<=1000){
		acc->setState(new MiddleState(this));
	}else if(point<=100){
		acc->setState(new PrimaryState(this));
	}
}

int main(int argv, char**argc)
{
    printf("************  test hello zc!!!   **************\n");
    /* add test code! */

	//注册用户 
	ForumAccount account("张三");
	
	//操作 
	account.writeNote(20);
	account.downloadFile(20);
	account.replyNote(100);
	account.writeNote(40);
	account.downloadFile(80);
	account.downloadFile(150);
	account.writeNote(1000);
	account.downloadFile(80);

    
    return 0;
}
